#define BLINKER_WIFI
#define BLINKER_MIOT_OUTLET

#define BLINKER_DUEROS_OUTLET

#define BLINKER_ALIGENIE_OUTLET

//#define BLINKER_WITHOUT_SSL

#include <Blinker.h>
#include <Servo.h>

char auth[] = "3247c5720d36";
char ssid[] = "Sweet_meng";
char pswd[] = "aita0116.";

BlinkerButton Button1("k1");

#define USB_F1 2
Servo myservo;
bool oState = false;

void heartbeat()
{
    BLINKER_LOG("heartbeat,state: ", oState);
    if (HIGH == oState)
    {
        Button1.print("on");
    }
    else
    {
        Button1.print("off");
    }
}

void button1_callback(const String &state)
{
    BLINKER_LOG("get button state: ", state);
    if (state == BLINKER_CMD_ON)
    {
        BLINKER_LOG("Toggle on!");
        Button1.print("on");
        digitalWrite(USB_F1, HIGH);
        myservo.write(98);
        delay(500);
        myservo.write(80);
        oState = true;
    }
    else if (state == BLINKER_CMD_OFF)
    {
        BLINKER_LOG("Toggle off!");
        Button1.print("off");
        digitalWrite(USB_F1, LOW);
        myservo.write(64); 
        delay(500);
        myservo.write(80);
        oState = false;
    }
    BlinkerMIOT.powerState(oState ? "on" : "off");
    BlinkerMIOT.print();

    BlinkerDuerOS.powerState(oState ? "on" : "off");
    BlinkerDuerOS.print();

    BlinkerAliGenie.powerState(oState ? "on" : "off");
    BlinkerAliGenie.print();
}

void miotPowerState(const String &state)
{
    BLINKER_LOG("need set power state: ", state);
    if (state == BLINKER_CMD_ON)
    {
        digitalWrite(USB_F1, HIGH);
        myservo.write(98);
        delay(500);
        myservo.write(80);
        oState = true;
    }
    else if (state == BLINKER_CMD_OFF)
    {
        digitalWrite(USB_F1, LOW);
        myservo.write(64); 
        delay(500);
        myservo.write(80);
        oState = false;
    }
    BlinkerMIOT.powerState(oState ? "on" : "off");
    BlinkerMIOT.print();
}

void miotQuery(int32_t queryCode)
{
    BLINKER_LOG("MIOT Query codes: ", queryCode);
    switch (queryCode)
    {
    case BLINKER_CMD_QUERY_ALL_NUMBER:
        BLINKER_LOG("MIOT Query All");
        BlinkerMIOT.powerState(oState ? "on" : "off");
        BlinkerMIOT.print();
        break;
    case BLINKER_CMD_QUERY_POWERSTATE_NUMBER:
        BLINKER_LOG("MIOT Query Power State");
        BlinkerMIOT.powerState(oState ? "on" : "off");
        BlinkerMIOT.print();
        break;
    default:
        BlinkerMIOT.powerState(oState ? "on" : "off");
        BlinkerMIOT.print();
        break;
    }
}

void duerPowerState(const String &state)
{
    BLINKER_LOG("need set power state: ", state);
    if (state == BLINKER_CMD_ON)
    {
        digitalWrite(USB_F1, HIGH);
        myservo.write(98);
        delay(500);
        myservo.write(80);
        oState = true;
    }
    else if (state == BLINKER_CMD_OFF)
    {
        digitalWrite(USB_F1, LOW);
        myservo.write(64); 
        delay(500);
        myservo.write(80);
        oState = false;
    }
    BlinkerDuerOS.powerState(oState ? "on" : "off");
    BlinkerDuerOS.print();
}

void duerQuery(int32_t queryCode)
{
    BLINKER_LOG("DuerOS Query codes: ", queryCode);
    switch (queryCode)
    {
    case BLINKER_CMD_QUERY_ALL_NUMBER:
        BLINKER_LOG("DuerOS Query All");
        BlinkerDuerOS.powerState(oState ? "on" : "off");
        BlinkerDuerOS.time(millis());
        BlinkerDuerOS.print();
        break;
    case BLINKER_CMD_QUERY_POWERSTATE_NUMBER:
        BLINKER_LOG("DuerOS Query Power State");
        BlinkerDuerOS.powerState(oState ? "on" : "off");
        BlinkerDuerOS.print();
        break;
    case BLINKER_CMD_QUERY_TIME_NUMBER:
        BLINKER_LOG("DuerOS Query time");
        BlinkerDuerOS.time(millis());
        BlinkerDuerOS.print();
        break;
    default:
        BlinkerDuerOS.powerState(oState ? "on" : "off");
        BlinkerDuerOS.time(millis());
        BlinkerDuerOS.print();
        break;
    }
}

void aligeniePowerState(const String &state)
{
    BLINKER_LOG("need set power state: ", state);
    if (state == BLINKER_CMD_ON)
    {
        digitalWrite(USB_F1, HIGH);
        myservo.write(98);
        delay(500);
        myservo.write(80);
        oState = true;
    }
    else if (state == BLINKER_CMD_OFF)
    {
        digitalWrite(USB_F1, LOW);
        myservo.write(64); 
        delay(500);
        myservo.write(80);
        oState = false;
    }
    BlinkerAliGenie.powerState(oState ? "on" : "off");
    BlinkerAliGenie.print();
}

void aligenieQuery(int32_t queryCode)
{
    BLINKER_LOG("AliGenie Query codes: ", queryCode);
    switch (queryCode)
    {
    case BLINKER_CMD_QUERY_ALL_NUMBER:
        BLINKER_LOG("AliGenie Query All");
        BlinkerAliGenie.powerState(oState ? "on" : "off");
        BlinkerAliGenie.print();
        break;
    case BLINKER_CMD_QUERY_POWERSTATE_NUMBER:
        BLINKER_LOG("AliGenie Query Power State");
        BlinkerAliGenie.powerState(oState ? "on" : "off");
        BlinkerAliGenie.print();
        break;
    default:
        BlinkerAliGenie.powerState(oState ? "on" : "off");
        BlinkerAliGenie.print();
        break;
    }
}

void dataRead(const String &data)
{
    BLINKER_LOG("Blinker readString: ", data);
    Blinker.vibrate();
    uint32_t BlinkerTime = millis();
    Blinker.print("millis", BlinkerTime);
}

void setup()
{
    Serial.begin(115200);
    BLINKER_DEBUG.stream(Serial);
    // BLINKER_DEBUG.debugAll();

    pinMode(USB_F1, OUTPUT);
    digitalWrite(USB_F1, LOW);
    myservo.attach(0);
    myservo.write(80);

    Button1.attach(button1_callback);
    Blinker.attachHeartbeat(heartbeat);

    Blinker.begin(auth, ssid, pswd);
    Blinker.attachData(dataRead);

    BlinkerMIOT.attachPowerState(miotPowerState);
    BlinkerMIOT.attachQuery(miotQuery);

    BlinkerDuerOS.attachPowerState(duerPowerState);
    BlinkerDuerOS.attachQuery(duerQuery);

    BlinkerAliGenie.attachPowerState(aligeniePowerState);
    BlinkerAliGenie.attachQuery(aligenieQuery);
}

void loop()
{
    Blinker.run();
}
